package com.kotlin.base.utils

import android.text.TextUtils
import cn.yzhg.lib.tools.LogTools
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.google.gson.reflect.TypeToken
import org.json.JSONException
import org.json.JSONObject
import java.lang.reflect.Type
import java.util.ArrayList
import java.util.HashMap

/**
 * 类 名: JsonUtil
 * 作 者: yzhg
 * 创 建: 2018/11/17 0017
 * 版 本: 1.0
 * 历 史: (版本) 作者 时间 注释
 * 描 述:
 */
class JsonUtil {


    companion object {
        private var manager: JsonUtil? = null
            /**
             * field 解释https://www.jishux.com/p/228468f108ac1bf4
             * 懒汉式加载
             */
            get() {
                if (field == null) {
                    field = JsonUtil()
                }
                return field
            }

        //线程安全的懒汉式
        @Synchronized
        fun get(): JsonUtil {
            return manager!!
        }

        /*双重锁单利模式*/
        val instance: JsonUtil by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { JsonUtil() }
    }


    /**
     * 把一个map变成json字符串
     *
     * @param map
     * @return
     */
    fun parseMapToJson(map: Map<*, *>): String? {
        try {
            val gson = Gson()
            return gson.toJson(map)
        } catch (e: Exception) {
        }

        return null
    }

    /**
     * 把一个json字符串变成对象
     *
     * @param json
     * @param cls
     * @return
     */
    fun <T> parseJsonToBean(json: String, cls: Class<T>): T? {
        val gson = Gson()
        var t: T? = null
        try {
            t = gson.fromJson(json, cls)
        } catch (e: Exception) {
        }

        return t
    }

    /**
     * 把json字符串变成map
     *
     * @param json
     * @return
     */
    fun parseJsonToMap(json: String): HashMap<String, Any>? {
        val gson = Gson()
        val type = object : TypeToken<HashMap<String, Any>>() {

        }.type
        var map: HashMap<String, Any>? = null
        try {
            map = gson.fromJson<HashMap<String, Any>>(json, type)
        } catch (e: Exception) {
        }

        return map
    }

    /**
     * 把json字符串变成集合
     * params: new TypeToken<List></List><yourbean>>(){}.getType(),
     *
     * @param json
     * @param type new TypeToken<List></List><yourbean>>(){}.getType()
     * @return
    </yourbean></yourbean> */
    fun parseJsonToList(json: String, type: Type): List<*>? {
        val gson = Gson()
        return gson.fromJson<List<*>>(json, type)
    }

    /**
     * 作 者: yzhg
     * 历 史: (版本) 1.0
     * 描 述: 将list集合转化为jaon字符串
     */
    fun parseListToJson(list: ArrayList<*>): String {
        val gson = Gson()
        return gson.toJson(list)
    }


    /**
     * 获取json串中某个字段的值，注意，只能获取同一层级的value
     *
     * @param json
     * @param key
     * @return
     */
    fun getFieldValue(json: String, key: String): String? {
        if (TextUtils.isEmpty(json))
            return null
        if (!json.contains(key))
            return ""
        val jsonObject: JSONObject?
        var value: String? = null
        try {
            jsonObject = JSONObject(json)
            value = jsonObject.getString(key)
        } catch (e: JSONException) {
            e.printStackTrace()
        }

        return value
    }

    fun <T> getObjectList(jsonString: String, cls: Class<T>): List<T> {
        val list = ArrayList<T>()
        try {
            val gson = Gson()
            val arry = JsonParser().parse(jsonString).asJsonArray
            for (jsonElement in arry) {
                list.add(gson.fromJson(jsonElement, cls))
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return list
    }


    /**
     * 解析json数组为ArrayList
     *
     * @param json  要解析的json
     * @param clazz 解析类
     * @return ArrayList
     */
    fun <T> parseToArrayList(json: String, clazz: Class<T>): ArrayList<T> {
        val type = object : TypeToken<ArrayList<JsonObject>>() {

        }.type
        val jsonObjects = Gson().fromJson<ArrayList<JsonObject>>(json, type)
        val arrayList = ArrayList<T>()
        for (jsonObject in jsonObjects) {
            arrayList.add(Gson().fromJson(jsonObject, clazz))
        }
        return arrayList
    }











}